package com.shigu.trade.service;

import com.opentae.data.mall.beans.*;
import com.opentae.data.mall.examples.WxRefundExample;
import com.opentae.data.mall.interfaces.*;
import com.opentae.data.mall.pojo.ManagerOrderData;
import com.opentae.data.mall.pojo.ToSendOrderData;
import com.shigu.MallResponse;
import com.shigu.PageResponse;
import com.shigu.account.enums.VipLevel;
import com.shigu.account.exception.UtilsAccountException;
import com.shigu.account.service.UserAccountService;
import com.shigu.exceptions.AdminException;
import com.shigu.pushMessage.service.AppPush;
import com.shigu.trade.enums.*;
import com.shigu.trade.uti.FeeExcelUtil;
import com.shigu.trade.vo.*;
import com.shigu.util.MoneyUtil;
import com.shigu.weixin.enums.WxConfigSource;
import com.shigu.weixin.service.PayApplyService;
import com.shigu.weixin.service.WxPayService;
import com.shigu.weixin.vo.WxRefundVo;
import com.sun.org.apache.regexp.internal.RE;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class TradeAdminService {
    private static final Logger logger = LoggerFactory.getLogger(TradeAdminService.class);

    @Autowired
    MallTradeMapper mallTradeMapper;
    @Autowired
    MallOrderLogisticsMapper mallOrderLogisticsMapper;
    @Autowired
    MallOrderMapper mallOrderMapper;
    @Autowired
    MallOrderRecordMapper mallOrderRecordMapper;
    @Autowired
    FeeExcelUtil feeExcelUtil;
    @Autowired
    MallItemMapper mallItemMapper;
    @Autowired
    MallRefundMapper mallRefundMapper;
    @Autowired
    UserAccountService userAccountService;
    @Autowired
    MallWalletMapper mallWalletMapper;
    @Autowired
    ManagerMallUserMapper managerMallUserMapper;

    @Autowired
    MallProvMapper mallProvMapper;
    @Autowired
    MallCityMapper mallCityMapper;
    @Autowired
    MallAreaMapper mallAreaMapper;

    @Autowired
    UserInviteInfoMapper userInviteInfoMapper;
    @Autowired
    MallBonusMapper mallBonusMapper;

    @Autowired
    AppPush appPush;

    @Autowired
    PayApplyService payApplyService;

    @Autowired
    WxRefundMapper wxRefundMapper;
    @Autowired
    WxPayService wxPayService;

    /**
     * @description 订单列表
     * @author 郭尔
     * @date 2019/1/12 15:18
     */
    public PageResponse<AllOrderVo> allOrderList(int page, int size, String tradeCode) {
        List<ManagerOrderData> list = mallOrderMapper.allOrderList(tradeCode, (page - 1) * size, size);
        int total = mallOrderMapper.countAllOrderList(tradeCode);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        PageResponse<AllOrderVo> response = new PageResponse<>();
        response.setTotal(total);
        response.setData(list.stream().map(o -> {
            AllOrderVo vo = new AllOrderVo();
            vo.setBuyer(o.getBuyer());
            vo.setBuyerId(o.getBuyerId());
            vo.setTradeCode(o.getTradeCode());
            vo.setImgUrl(o.getImgUrl());
            vo.setSku(o.getSku());
            vo.setItemCode(o.getItemCode());
            vo.setPayMoney(MoneyUtil.formatPriceMoney(o.getPayMoney() + o.getPostFee()));
            vo.setPostFee(MoneyUtil.formatPriceMoney(o.getPostFee()));

            vo.setProvName(o.getProvName());
            vo.setCityName(o.getCityName());
            vo.setAreaName(o.getAreaName());
            vo.setReceiveDetail(o.getReceiveDetail());
            vo.setReceiveName(o.getReceiveName());
            vo.setReceiveTelephone(o.getReceiveTelephone());

            vo.setNum(o.getNum());
            vo.setTitle(o.getTitle());
            vo.setRemark(o.getRemark());
            vo.setPostCompany(StringUtils.isBlank(o.getPostCompany()) ? "" : o.getPostCompany());
            vo.setPostCode(StringUtils.isBlank(o.getPostCode()) ? "" : o.getPostCode());
            vo.setPayTime(o.getPayTime() == null ? "" : sdf.format(o.getPayTime()));
            vo.setSendTime(o.getSendTime() == null ? "" : sdf.format(o.getSendTime()));
            return vo;
        }).collect(Collectors.toList()));
        return response.success();
    }

    /**
     * @description 发货
     * @author 郭尔
     * @date 2019/1/12 15:23
     */
    public synchronized MallResponse orderSend(String tradeCode, String postCompany, String postCode, String remark) throws UtilsAccountException {
        MallTrade trade = mallTradeMapper.selByTradeCode(tradeCode);
        MallOrder order = mallOrderMapper.selectOrderByTradeCode(tradeCode);
        if(trade.getSendStatus() == TradeSendStatus.SEND.getValue()){
            return new MallResponse().success();
        }

        MallOrderRecord record = new MallOrderRecord();
        record.setChangeTime(new Date());
        record.setTradeCode(tradeCode);
        record.setTid(trade.getTid());
        record.setFromStatus(RecordFromStatus.SEND.getValue());
        mallOrderRecordMapper.insertSelective(record);

        trade.setSendStatus(TradeSendStatus.SEND.getValue());
        mallTradeMapper.updateByPrimaryKeySelective(trade);

        MallOrderLogistics logistics = mallOrderLogisticsMapper.selectByTradeCode(tradeCode);
        logistics.setPostCompany(postCompany);
        logistics.setPostCode(postCode);
        mallOrderLogisticsMapper.updateByPrimaryKey(logistics);
        if (StringUtils.isNotBlank(remark)) {
            mallOrderMapper.addRemark(tradeCode, remark);
        }

        mallItemMapper.changeSales(order.getItemId(),order.getNum());

        //用户消费总额
        ManagerMallUser mallUser = managerMallUserMapper.selectByPrimaryKey(trade.getBuyerId());
        mallUser.setHaveCost(mallUser.getHaveCost() + trade.getTotalMoney());
        managerMallUserMapper.updateByPrimaryKeySelective(mallUser);

     //   mallBonusService.doDistributeReward(tradeCode,trade.getRewardId());

        // 通知
        if(trade.getRewardId()!=null && trade.getSource() == TradeSource.GZH.getValue()){
            UserInviteInfo info = userInviteInfoMapper.selectByPrimaryKey(trade.getRewardId());
            if(StringUtils.isNotBlank(info.getDeviceCid())){
                appPush.sendToSingle(info.getDeviceCid(),"通知","您有一个分销订单已发货","/pages/wp/mallCommission");
            }else {
                logger.error("userId="+trade.getRewardId()+" have not get cid ");
            }
        }


        return new MallResponse().success();
    }


    /**
     * @description 待发货订单列表
     * @author 郭尔
     * @date 2019/1/12 15:56
     */
    public PageResponse<ToSendVo> toSendList(int page, int size, String tradeCode,String agentId) {
        List<ToSendOrderData> list = mallOrderMapper.toSendList(tradeCode, (page - 1) * size, size,agentId);
        int total = mallOrderMapper.countToSendOrderList(tradeCode,agentId);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        PageResponse<ToSendVo> response = new PageResponse<>();
        response.setTotal(total);
        response.setData(list.stream().map(o -> {
            ToSendVo vo = new ToSendVo();
            vo.setBuyer(o.getBuyer());
            vo.setBuyerId(o.getBuyerId());
            vo.setTradeCode(o.getTradeCode());
            vo.setImgUrl(o.getImgUrl());
            vo.setSku(o.getSku());
            vo.setTitle(o.getTitle());
            vo.setItemCode(o.getItemCode());
            vo.setPayMoney(MoneyUtil.formatPriceMoney(o.getPayMoney() + o.getPostFee()));
            vo.setPostFee(MoneyUtil.formatPriceMoney(o.getPostFee()));
            vo.setProvName(o.getProvName());
            vo.setCityName(o.getCityName());
            vo.setAreaName(o.getAreaName());
            vo.setReceiveDetail(o.getReceiveDetail());
            vo.setReceiveName(o.getReceiveName());
            vo.setReceiveTelephone(o.getReceiveTelephone());
            vo.setNum(o.getNum());
            vo.setPayTime(o.getPayTime() == null ? "" : sdf.format(o.getPayTime()));
            vo.setGoodsNo(o.getGoodsNo());
            vo.setStoreNum(o.getStoreNum());
            if (o.getRewardId() != null) {
                //查询推荐人信息
                AgentVo agentVo = agentInfo(o.getRewardId());
                vo.setAgent(agentVo);
            }

            return vo;
        }).collect(Collectors.toList()));
        return response.success();
    }

    /**
     *
     * @description 获取邀请人信息
     * @author 郭尔
     * @date 2019-06-13 15:14
     */
    private AgentVo agentInfo(Long id){
        UserInviteInfo info = userInviteInfoMapper.selectByPrimaryKey(id);
        if(info==null){
            return null;
        }
        AgentVo vo = new AgentVo();

        vo.setAgentId(id);
        vo.setDutyName(VipLevel.selByValue(info.getVipLevel()).getTitle());

        ManagerMallUser user = managerMallUserMapper.selectFieldsByPrimaryKey(id, "nick");
        vo.setNick(user.getNick());
        return vo;
    }

    /**
     * @description 导出全部订单
     * @author 郭尔
     * @date 2019/1/14 17:16
     */
    public void exportTradeList(OutputStream out) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String[] header = {"订单号", "下单时间", "发货时间", "买家id", "买家昵称", "收货人电话", "收货人", "收货地址", "商品编号", "实付金额", "规格", "数量", "物流单号", "物流公司", "备注", "支付方式"};
        List<ManagerOrderData> orderList = mallOrderMapper.orderList();
        List<AllPaidOrderVo> list = orderList.stream().map(o -> {
            AllPaidOrderVo vo = new AllPaidOrderVo();
            vo.setBuyer(o.getBuyer());
            vo.setBuyerId(o.getBuyerId());
            vo.setTradeCode(o.getTradeCode());
            vo.setSku(o.getSku());
            vo.setItemCode(o.getItemCode());
            vo.setPayMoney(MoneyUtil.formatPriceMoney(o.getPayMoney()));
            vo.setReceiveDetail(o.getProvName() + o.getCityName() + o.getAreaName() + o.getReceiveDetail());
            vo.setReceiveName(o.getReceiveName());
            vo.setReceiveTelephone(o.getReceiveTelephone());
            vo.setNum(o.getNum());
            vo.setRemark(StringUtils.isBlank(o.getRemark()) ? " " : o.getRemark());
            vo.setPostCompany(StringUtils.isBlank(o.getPostCompany()) ? " " : o.getPostCompany());
            vo.setPostCode(StringUtils.isBlank(o.getPostCode()) ? " " : o.getPostCode());
            vo.setPayTime(o.getPayTime() == null ? " " : sdf.format(o.getPayTime()));
            vo.setSendTime(o.getSendTime() == null ? " " : sdf.format(o.getSendTime()));
            vo.setPayWay(PayWay.selByValue(o.getPayWay()).getTitle());
            return vo;
        }).collect(Collectors.toList());

        feeExcelUtil.exportExcel("订单", header, list, out, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * @description 订单支付成功
     * @author 郭尔
     * @date 2019/1/15 14:10
     */
    @Transactional(rollbackFor = Exception.class)
    public MallResponse dowithTrade(String tradeCode, Boolean success, PayWay payWay) {
        if (success) {
            //订单变为支付成功a
            //去除了支付后加上已消费

            MallTrade trade = mallTradeMapper.selByTradeCode(tradeCode);
            trade.setPayStatus(TradePayStatus.HASPAY.getValue());
            trade.setPayWay(payWay.getValue());
            mallTradeMapper.updateByPrimaryKeySelective(trade);
            MallOrderRecord record = new MallOrderRecord();
            record.setTradeCode(tradeCode);
            record.setTid(trade.getTid());
            record.setChangeTime(new Date());
            record.setFromStatus(RecordFromStatus.PAY.getValue());
            mallOrderRecordMapper.insertSelective(record);

//            ManagerMallUser mallUser = managerMallUserMapper.selectByPrimaryKey(trade.getBuyerId());
//            mallUser.setHaveCost(mallUser.getHaveCost()+trade.getTotalMoney());
//            managerMallUserMapper.updateByPrimaryKeySelective(mallUser);
        }
        return new MallResponse().success();
    }

    /**
     * @description 订单备注
     * @author 郭尔
     * @date 2019/1/19 11:27
     */
    public MallResponse remarkOrder(String tradeCode, String remark) {
        MallOrder order = mallOrderMapper.selectOrderByTradeCode(tradeCode);
        if (order != null) {
            order.setRemark(remark);
            mallOrderMapper.updateByPrimaryKeySelective(order);
        }
        return new MallResponse().success();
    }

    /**
     * @description 关闭交易
     * @author 郭尔
     * @date 2019/1/19 14:41
     */
    public MallResponse closeTrade(String tradeCode) {
        Long tid = mallTradeMapper.selTidByTradeCode(tradeCode);
        MallTrade trade = new MallTrade();
        trade.setTid(tid);
        trade.setTradeStatus(TradeStatus.CLOSED.getValue());
        trade.setSendStatus(TradeSendStatus.RETREAT.getValue());
        mallTradeMapper.updateByPrimaryKeySelective(trade);

        MallOrderRecord record = new MallOrderRecord();
        record.setTid(tid);
        record.setChangeTime(new Date());
        record.setTradeCode(tradeCode);
        record.setToStatus(RecordToStatus.REFUND.getValue());
        mallOrderRecordMapper.insertSelective(record);
        return new MallResponse().success();
    }

    /**
     * @description 导出订单
     * @author 郭尔
     * @date 2019/1/14 17:16
     */
    public void exportNoSend(OutputStream out) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String[] header = {"订单号", "下单时间", "买家id", "买家昵称", "收货人电话", "收货人", "收货地址", "商品编号", "实付金额", "规格", "数量", "支付方式"};
        List<ToSendOrderData> orderList = mallOrderMapper.noSendList();
        List<NoSendVo> list = orderList.stream().map(o -> {
            NoSendVo vo = new NoSendVo();
            vo.setBuyer(o.getBuyer() + "");
            vo.setBuyerId(o.getBuyerId());
            vo.setTradeCode(o.getTradeCode());
            vo.setSku(o.getSku());
            vo.setItemCode(o.getItemCode());
            vo.setPayMoney(MoneyUtil.formatPriceMoney(o.getPayMoney()));
            vo.setReceiveDetail(o.getProvName() + o.getCityName() + o.getAreaName() + o.getReceiveDetail());
            vo.setReceiveName(o.getReceiveName());
            vo.setReceiveTelephone(o.getReceiveTelephone());
            vo.setNum(o.getNum());
            vo.setPayTime(o.getPayTime() == null ? " " : sdf.format(o.getPayTime()));
            vo.setPayWay(PayWay.selByValue(o.getPayWay()).getTitle());
            return vo;
        }).collect(Collectors.toList());

        feeExcelUtil.exportExcel("订单", header, list, out, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * @description 退款退货
     * @author 郭尔
     * @date 2019-05-13 9:34
     */
    public MallResponse refundTrade(String tradeId) throws AdminException {
        MallTrade trade = mallTradeMapper.selectByPrimaryKey(tradeId);
        if (trade.getPayStatus() != TradePayStatus.HASPAY.getValue()) {
            throw new AdminException("订单支付状态不符，不能退款");
        }

        if (trade.getSendStatus() == TradeSendStatus.RECEIVE.getValue()) {
            throw new AdminException("该订单已确认收货");
        }
        if (trade.getSendStatus() == TradeSendStatus.RETREAT.getValue()
                || trade.getSendStatus() == TradeSendStatus.RETREATING.getValue()) {
            throw new AdminException("该订单已退货");
        }
        //改变订单状态
        trade.setSendStatus(TradeSendStatus.RETREAT.getValue());//改为退货状态
        mallTradeMapper.updateByPrimaryKeySelective(trade);
        //插入一条退货记录,订单记录表插入记录
        MallRefund refund = new MallRefund();
        refund.setTid(Long.valueOf(tradeId));
        refund.setRefundMoney(trade.getTotalMoney());
        refund.setCreateTime(new Date());
        refund.setBuyerId(trade.getBuyerId());
        //refund  examin_status 默认1 之后处理直接改变 examin_status
        mallRefundMapper.insertSelective(refund);

        MallOrderRecord record = new MallOrderRecord();
        record.setTradeCode(trade.getTradeCode());
        record.setToStatus(TradeSendStatus.RETREATING.getValue());
        record.setChangeTime(new Date());
        record.setTid(Long.valueOf(tradeId));
        mallOrderRecordMapper.insertSelective(record);
        return new MallResponse().success();
    }

    /**
     * @param status 1全部 2退款的
     * @description 订单列表
     * @author 郭尔
     * @date 2019/1/12 15:18
     */
    public PageResponse<SendVo> sendedList(int page, int size, String tradeCode, String buyerId, Integer status,String agentId) {
        List<ManagerOrderData> list = mallOrderMapper.haveSendList((page - 1) * size, size, tradeCode, buyerId, status,agentId);
        int total = mallOrderMapper.countSendedList(tradeCode, buyerId, status,agentId);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        PageResponse<SendVo> response = new PageResponse<>();
        response.setTotal(total);
        response.setData(list.stream().map(o -> {
            SendVo vo = new SendVo();
            vo.setBuyer(o.getBuyer());
            vo.setBuyerId(o.getBuyerId());
            vo.setTradeCode(o.getTradeCode());
            vo.setImgUrl(o.getImgUrl());
            vo.setSku(o.getSku());
            vo.setItemCode(o.getItemCode());
            vo.setPayMoney(MoneyUtil.formatPriceMoney(o.getPayMoney() + o.getPostFee()));
            vo.setPostFee(MoneyUtil.formatPriceMoney(o.getPostFee()));
            vo.setTradeId(o.getTid());
            vo.setProvName(o.getProvName());
            vo.setCityName(o.getCityName());
            vo.setAreaName(o.getAreaName());
            vo.setReceiveDetail(o.getReceiveDetail());
            vo.setReceiveName(o.getReceiveName());
            vo.setReceiveTelephone(o.getReceiveTelephone());
            vo.setSendStatus(o.getSendStatus());
            vo.setNum(o.getNum());
            vo.setTitle(o.getTitle());
            vo.setRemark(o.getRemark());
            vo.setPostCompany(StringUtils.isBlank(o.getPostCompany()) ? "" : o.getPostCompany());
            vo.setPostCode(StringUtils.isBlank(o.getPostCode()) ? "" : o.getPostCode());
            vo.setPayTime(o.getPayTime() == null ? "" : sdf.format(o.getPayTime()));
            vo.setSendTime(o.getSendTime() == null ? "" : sdf.format(o.getSendTime()));

            if (o.getRewardId() != null) {
                //查询推荐人信息
                AgentVo agentVo = agentInfo(o.getRewardId());
                vo.setAgent(agentVo);
            }
            return vo;
        }).collect(Collectors.toList()));
        return response.success();
    }

    /**
     * @description 修改收货人信息
     * @author 郭尔
     * @date 2019-06-13 13:40
     */
    public MallResponse changeTradeReceive(String tradeCode, String provName, String cityName, String areaName,
                                           String receiveName, String receiveAddress, String receiveTelephone) throws AdminException {
        MallTrade trade = mallTradeMapper.selByTradeCode(tradeCode);
        if (trade == null) {
            throw new AdminException("订单不存在");
        }
        //修改
        MallOrderLogistics addrInfo = mallOrderLogisticsMapper.selectByTradeCode(tradeCode);

        addrInfo.setAreaName(areaName);
        addrInfo.setCityName(cityName);
        addrInfo.setProvName(provName);
        addrInfo.setReceiveName(receiveName);
        addrInfo.setReceiveTelephone(receiveTelephone);
        addrInfo.setAddressDetail(receiveAddress);

        mallOrderLogisticsMapper.updateByPrimaryKeySelective(addrInfo);

        return new MallResponse();
    }

    /**
     *
     * @description
     * @author 郭尔
     * @date 2019-11-27 13:14
     */
    public TradeBonusResponse tradeBonus(String tradeCode){
        MallBonus bonus = mallBonusMapper.selTradeBonus(tradeCode);
        TradeBonusResponse response = new TradeBonusResponse();
        BeanUtils.copyProperties(bonus,response);
        return response.success();
    }

    /**
    *
    * @param tradeCode
    * @Author 过儿
    * @Date 2019/12/18
    */
    public MallResponse tradeWxRefund(String tradeCode) throws Exception {
        MallTrade trade = mallTradeMapper.selByTradeCode(tradeCode);
        if(trade.getPayWay() == PayWay.WXPAY.getValue()){
            closeTrade(tradeCode);
            payApplyService.wxRefund(trade.getPayMoney(),tradeCode,trade.getSource());
        }
        return new MallResponse().success();
    }
    
    /** 
    * 
    * @param
    * @Author 过儿 
    * @Date 2019/12/20 
    */
    public RefundResultResponse queryWxRefund(String tradeCode) throws Exception {
        WxRefundExample example = new WxRefundExample();
        example.createCriteria().andTradeCodeEqualTo(tradeCode);
        List<WxRefund> list = wxRefundMapper.selectByExample(example);
        if(list.isEmpty()){
            throw new AdminException("未查询到退款信息");
        }
        WxRefund refund = list.get(0);
        WxRefundVo vo = wxPayService.queryRefund(refund.getRefundCode(), refund.getWxNo(), refund.getRefundId());
        RefundResultResponse response = new RefundResultResponse();
        if (vo.getSuccess()){
            response.setRefundId(vo.getRefundId());
            response.setOutTradeNo(vo.getOutTradeNo());
            response.setOutRefundNo(vo.getOutRefundNo());
            response.setRefundFee(MoneyUtil.formatMoney( Double.valueOf(vo.getRefundFee())/100));
        }
        return response.success();

    }
}
